package base.widgets;

import java.util.HashMap;
import java.util.Map;

import org.redr.canvas.OSPath;
import org.redr.canvas.RRW;
import org.redr.canvas.RedRApplication;
import org.redr.widgetGUI.core.CommitButton;
import org.redr.widgetGUI.core.RFormulaEntry;
import org.redr.widgetGUI.core.TextEdit;
import org.redr.widgetGUI.settings.WidgetSettings;
import org.rosuda.REngine.REXP;

import base.signals.RDataFrameInput;
import base.signals.RLMOutput;

import com.trolltech.qt.gui.QTextOption.WrapMode;


public class LinearModel extends RRW {
	public static final String name = "Linear Model";
	public static final String summary = "Generates a Linear Model Fit";
	public static final String details = "This widget allows access to the R lm function.  This is used to generate a linear model.";
	public static final String icon = OSPath.join(RedRApplication.parentDir, "coreIcons", "default.png").getAbsolutePath();
	private RFormulaEntry formulaEntry;
	private TextEdit modelText;
	private CommitButton commitButton;
    
	public LinearModel(WidgetSettings ws) {
		super(ws);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void initSignals() {
		// TODO Auto-generated method stub
		this.addInput(new RDataFrameInput(this, "id1", _("Data Table"), false));
		this.addOutput(new RLMOutput(this, "id1", _("Fitted Linear Model")));
	}

	@Override
	protected void initGUI() {
		this.formulaEntry	=	new	RFormulaEntry(this.gui.controlArea, (WidgetSettings) this.settings.getSettings("formulaEntry")
				.setSetting("label", "Linear Model Formula Entry"));
		this.modelText		=	new TextEdit(this.gui.controlArea, (WidgetSettings) this.settings.getSettings("modelText")
				.setSetting("label", "Linear Model Output"));
		this.modelText.widget().setFontFamily("courier");
		this.modelText.widget().setWordWrapMode(WrapMode.NoWrap);
		this.commitButton	=	new CommitButton(this.gui.bottomAreaRight, (WidgetSettings) this.settings.getSettings("commitButton")
				.setSetting("label", "Commit"));
	}

	@Override
	protected void initVariables() {
		this.rvarSettings.setDefault("lm", this.makeVarName("lm"));
	}

	@Override
	protected void dataInput(String id, Object data, String widgetId) {
		if (id.equals("id1")){
			this.settings.setSetting("data", (String) data);
			try {
				REXP names	=	this.R(String.format("names(%s)", this.settings.getSetting("data")));
				Map<String, String> items	=	new HashMap<String, String>();
				for ( String s : names.asStrings() ){
					items.put(s, s);
				}
				this.formulaEntry.update(items);
				
				if ( this.commitButton.processOnInput() ){
					this.commitFunction();
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}
	
	protected void commitFunction(){
		try{
			if ( this.settings.getSetting("data") == null | this.settings.getSetting("data").equals("") ){
				this.setStatus(1, "Data Not Connected");
				return;
			}
			
			String[] formula	=	this.formulaEntry.Formula();
			if (formula[1].equals("")){
				this.setStatus(1, "No appropriate formula entered");
				return;
			}
			
			this.nullR(String.format(
					"%s<-lm(%s ~ %s, data = %s)",
					this.rvarSettings.getSetting("lm"),
					formula[0],
					formula[1],
					this.settings.getSetting("data"))
				);
			this.outputsGet("id1").setData(
					this.rvarSettings.getSetting("lm"));
			this.send("id1");
		} catch (Exception e) {
			e.printStackTrace();
			this.setStatus(2, "Processing error occurred\\n" + e.toString());
		}
	}

}
